www.gusucode.com > VC++ 解析emf文件结构并显示-源码程序 > VC++ 解析emf文件结构并显示-源码程序/code/EmfReader/EmfReaderDlg.cpp
//Download by http://www.NewXing.com // EmfReaderDlg.cpp : 实现文件 // #include "stdafx.h" #include "EmfReader.h" #include "EmfReaderDlg.h" #include "Wingdi.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // 用于应用程序“关于”菜单项的 CAboutDlg 对话框 class CAboutDlg : public CDialog { public: CAboutDlg(); // 对话框数据 enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 // 实现 protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // CEmfReaderDlg 对话框 CEmfReaderDlg::CEmfReaderDlg(CWnd* pParent /*=NULL*/) : CDialog(CEmfReaderDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CEmfReaderDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CEmfReaderDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_BN_CLICKED(IDOK, &CEmfReaderDlg::OnBnClickedOk) ON_BN_CLICKED(IDC_BUTTON_NEXT, &CEmfReaderDlg::OnBnClickedButtonNext) ON_BN_CLICKED(IDCANCEL, &CEmfReaderDlg::OnBnClickedCancel) END_MESSAGE_MAP() // CEmfReaderDlg 消息处理程序 BOOL CEmfReaderDlg::OnInitDialog() { CDialog::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 Initialize( ) ; return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } void CEmfReaderDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // 如果向对话框添加最小化按钮,则需要下面的代码 // 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序, // 这将由框架自动完成。 void CEmfReaderDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { if( m_hDCMem && m_EnhMetaHeader.szlDevice.cx > 0 ) { HDC hDC = ::GetWindowDC(m_hWnd) ; // Capture screen into bitmap //RT_INFO_TRACE_THIS("CMirrorDriverManager::CaptureScreen.BEGIN rect:" <<rect.tl.x << ","<<rect.tl.y << "," <<rect.br.x << "," <<rect.br.y ) ; RECT rect ; GetClientRect( & rect ) ; int nOldMode = SetStretchBltMode( m_hDCMem, STRETCH_HALFTONE); //BOOL bRet = BitBlt( hDC, rect.left + 5, rect.top + 30 , // (rect.right-rect.left) - 5 , // (rect.bottom-rect.top)-100, // m_hDCMem , 800 , 800 , SRCCOPY ) ; BOOL blitok = StretchBlt(hDC, rect.left + 5, rect.top + 30 , (rect.right-rect.left) - 5 , (rect.bottom-rect.top)-100, m_hDCMem , 0 , 0 , m_EnhMetaHeader.szlDevice.cx , m_EnhMetaHeader.szlDevice.cy , SRCCOPY ) ; //RT_INFO_TRACE_THIS("CMirrorDriverManager::CaptureScreen.END") ; SetStretchBltMode( m_hDCMem, nOldMode); // Select the old bitmap back into the memory DC ::ReleaseDC( m_hWnd , hDC ) ; } CDialog::OnPaint(); } } //当用户拖动最小化窗口时系统调用此函数取得光标显示。 // HCURSOR CEmfReaderDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } void CEmfReaderDlg::OnBnClickedOk() { CString szFilter( L"Emf Files (*.emf)|*.emf||" ) ; CFileDialog FileDlg(TRUE,CString( L"EMF") ,NULL, OFN_FILEMUSTEXIST|OFN_NONETWORKBUTTON| OFN_PATHMUSTEXIST,szFilter); FileDlg.DoModal(); // To get the selected file's path and name CString strFileName; strFileName = FileDlg.GetPathName(); if(strFileName.IsEmpty()) return ; TRACE(L"FileName:%s\n",strFileName) ; memset( &m_EnhMetaHeader , 0 , sizeof( ENHMETAHEADER ) ) ; m_strEmfFile = strFileName ; if( m_File.GetFileName().GetLength() > 0 ) m_File.Close() ; if (!m_File.Open(strFileName ,CFile::modeRead , &m_FileException)) { TCHAR szError[1024]; m_FileException.GetErrorMessage(szError, 1024); TRACE(L"Couldn't open source file::%s,errormsg:s\n",strFileName,szError) ; return ; } DWORD dwReaded ; dwReaded = m_File.Read( &m_EnhMetaHeader , sizeof( ENHMETAHEADER ) ) ; if( dwReaded < sizeof( ENHMETAHEADER ) ) { TRACE("Read meta header error!\n") ; m_File.Close() ; return ; } if( m_EnhMetaHeader.dSignature!=0x464d4520) { TRACE("This file is not emf file.\n"); m_File.Close() ; return; } if ( m_EnhMetaHeader.nDescription > 0 ) { //file.Seek(eh.offDescription,CFile::begin); TCHAR *szDesciption ; szDesciption = new TCHAR[m_EnhMetaHeader.nDescription+1] ; memset( szDesciption , 0 , sizeof( TCHAR) * (m_EnhMetaHeader.nDescription+1)); dwReaded = m_File.Read(szDesciption , m_EnhMetaHeader.nDescription * sizeof( TCHAR) ) ; if( dwReaded == m_EnhMetaHeader.nDescription * sizeof( TCHAR) ) { TRACE(L"description:%s\n",szDesciption); } //file.Seek( sizeof( ENHMETAHEADER ) , CFile::begin) ; delete szDesciption ; } CreateMemDCandBitmap() ; m_dwEmfRecord = 0 ; } void CEmfReaderDlg::DoRecord( DWORD iType , DWORD nSize , LPBYTE lpData ) { switch( iType ) { case EMR_SETPIXELV: case EMR_SETMAPPERFLAGS: case EMR_SETCOLORADJUSTMENT: case EMR_OFFSETCLIPRGN: case EMR_SCALEVIEWPORTEXTEX: case EMR_SCALEWINDOWEXTEX: case EMR_SETWORLDTRANSFORM: case EMR_SELECTPALETTE: case EMR_CREATEPALETTE: case EMR_SETPALETTEENTRIES: case EMR_RESIZEPALETTE: case EMR_EXTFLOODFILL: case EMR_POLYDRAW: case EMR_SETARCDIRECTION: case EMR_SETMITERLIMIT: case EMR_GDICOMMENT: case EMR_FRAMERGN: case EMR_INVERTRGN: case EMR_PAINTRGN: case EMR_STRETCHBLT: case EMR_MASKBLT: case EMR_PLGBLT: case EMR_SETDIBITSTODEVICE: case EMR_POLYDRAW16: case EMR_CREATEMONOBRUSH: case EMR_CREATEDIBPATTERNBRUSHPT: case EMR_POLYTEXTOUTA: case EMR_POLYTEXTOUTW: case EMR_CREATECOLORSPACE: case EMR_GLSRECORD: case EMR_GLSBOUNDEDRECORD: case EMR_PIXELFORMAT: case EMR_RESERVED_105: case EMR_RESERVED_106: case EMR_RESERVED_107: case EMR_RESERVED_108: case EMR_RESERVED_109: case EMR_RESERVED_110: case EMR_COLORCORRECTPALETTE: case EMR_SETICMPROFILEA: case EMR_SETICMPROFILEW: case EMR_ALPHABLEND: case EMR_TRANSPARENTBLT: case EMR_RESERVED_117: case EMR_GRADIENTFILL: case EMR_RESERVED_119: case EMR_RESERVED_120: case EMR_COLORMATCHTOTARGETW: case EMR_CREATECOLORSPACEW: TRACE("RECORDTYPE:%ld,size:%ld\n",iType , nSize) ; break ; case EMR_EOF: case EMR_HEADER: break ; case EMR_POLYLINE: case EMR_POLYBEZIER : case EMR_POLYGON: case EMR_POLYBEZIERTO: case EMR_POLYLINETO: EmrPolyX( lpData ) ; break ; case EMR_POLYLINE16: case EMR_POLYBEZIER16 : case EMR_POLYGON16: case EMR_POLYBEZIERTO16: case EMR_POLYLINETO16: EmrPoly16X( lpData ) ; break ; case EMR_BITBLT: EmrBitBlt( lpData ) ; break ; case EMR_EXTTEXTOUTA: case EMR_EXTTEXTOUTW: EmrExtTextOutW( lpData ) ; break ; case EMR_STRETCHDIBITS: EmrStretchDibits( lpData ) ; break ; case EMR_SELECTOBJECT: EmrSelectObject( lpData , FALSE ) ; break ; case EMR_DELETEOBJECT: EmrSelectObject( lpData , TRUE ) ; break ; case EMR_ABORTPATH: case EMR_BEGINPATH: case EMR_ENDPATH: case EMR_CLOSEFIGURE: case EMR_FLATTENPATH: case EMR_WIDENPATH: case EMR_SETMETARGN: case EMR_SAVEDC: case EMR_REALIZEPALETTE: EmrDC( lpData ) ; break ; case EMR_RESTOREDC: EmrRestoreDC( lpData ) ; break ; case EMR_MOVETOEX: case EMR_LINETO: EmrMoveX( lpData ) ; break ; case EMR_SETTEXTCOLOR: case EMR_SETBKCOLOR: EmrSetBkOrTextColor( lpData ) ; break ; case EMR_SELECTCLIPPATH: case EMR_SETBKMODE: case EMR_SETMAPMODE: case EMR_SETPOLYFILLMODE: case EMR_SETROP2: case EMR_SETSTRETCHBLTMODE: case EMR_SETTEXTALIGN: case EMR_SETICMMODE: case EMR_SETLAYOUT: EmrSetBkOrOtherMode(lpData) ; break ; case EMR_SETWINDOWEXTEX: case EMR_SETVIEWPORTEXTEX: EmrSetWindowOrViewPortExtEX(lpData) ; break ; case EMR_SETWINDOWORGEX: case EMR_SETVIEWPORTORGEX: case EMR_SETBRUSHORGEX: EmrSetWindowOrViewPortEX(lpData) ; break ; case EMR_EXTCREATEFONTINDIRECTW: EmrExtCreateFontIndirectW( lpData ) ; break ; case EMR_SETCOLORSPACE: case EMR_DELETECOLORSPACE: EmrSetColorSpace( lpData ) ; break ; case EMR_CREATEBRUSHINDIRECT: EmrCreateBrushIndirect( lpData ) ; break ; case EMR_EXTCREATEPEN: EmrExtCreatePen( lpData ) ; break ; case EMR_MODIFYWORLDTRANSFORM: EmrModifyWorldTransForm( lpData ) ; break ; case EMR_EXTSELECTCLIPRGN: EmrExtSelectClipRgn( lpData ) ; break ; case EMR_INTERSECTCLIPRECT: case EMR_EXCLUDECLIPRECT: EmrInterSelectClipRect( lpData ) ; break ; case EMR_FILLPATH: case EMR_STROKEANDFILLPATH: case EMR_STROKEPATH: EmrStrokePath( lpData ) ; break ; case EMR_POLYPOLYLINE16: case EMR_POLYPOLYGON16: EmrPolyPolyLine16( lpData ) ; break ; case EMR_POLYPOLYLINE: case EMR_POLYPOLYGON: EmrPolyPolyLine( lpData ) ; break ; case EMR_CREATEPEN: EmrCreatePen( lpData ) ; break ; case EMR_ANGLEARC: EmrAngleArc( lpData ) ; break ; case EMR_ELLIPSE: case EMR_RECTANGLE: EmrRectangle( lpData ) ; break ; case EMR_ROUNDRECT: EmrRoundRect( lpData ) ; break ; case EMR_ARC: case EMR_CHORD: case EMR_ARCTO: case EMR_PIE: EmrArc( lpData ) ; break ; case EMR_FILLRGN: EmrFillRgn( lpData ) ; break ; } } void CEmfReaderDlg::OnBnClickedButtonNext() { DWORD iType ; DWORD nSize ; LPBYTE lpParam ; while( TRUE ) { if( m_File.GetFileName().GetLength() == 0 ) return ; DWORD dwReaded = m_File.Read( &iType , 4 ) ; if( dwReaded < 4 ) return ; dwReaded = m_File.Read( &nSize , 4 ) ; if( dwReaded < 4 ) return ; lpParam = new BYTE[nSize ]; memset( lpParam , 0 , nSize ) ; memcpy( lpParam , &iType , 4 ) ; memcpy( lpParam + 4 , &nSize , 4 ) ; if( lpParam == NULL ) return ; if( nSize > 8 ) { dwReaded = m_File.Read(lpParam + 8, nSize - 8 ) ; if( dwReaded < nSize - 8 ) return ; } m_dwEmfRecord ++ ; TRACE("recorder:%ld:",m_dwEmfRecord ) ; DoRecord( iType , nSize , lpParam ) ; delete lpParam ; if( iType == EMR_EOF || m_dwEmfRecord % 20 == 0 ) { OnPaint(); if( iType == EMR_EOF ) { m_File.Close() ; return ; } } } } void CEmfReaderDlg::OnBnClickedCancel() { UnInitialize() ; OnCancel(); } void CEmfReaderDlg::Initialize( ) { m_dwEmfRecord = 0 ; m_hDCMem = NULL ; // Handle to the memory device context m_hBitmap = NULL ; // Handle to the new bitmap } void CEmfReaderDlg::ReleaseAllObjs() { if( m_hBitmap ) { DeleteObject( m_hBitmap ) ; m_hBitmap = NULL ; } if( m_hDCMem ) { DeleteDC( m_hDCMem ) ; m_hDCMem = NULL ; } list<HGDIOBJECT_NODE>::iterator it , it1 ; it = m_listGdiObj.begin() ; while( it != m_listGdiObj.end( ) ) { it1 = it ; it++ ; HGDIOBJECT_NODE node = (HGDIOBJECT_NODE)(*it1) ; DeleteObject( node.hGidObj ) ; m_listGdiObj.erase( it1 ) ; } } void CEmfReaderDlg::UnInitialize() { if( m_File.GetFileName().GetLength() > 0 ) m_File.Close() ; ReleaseAllObjs( ) ; } BOOL CEmfReaderDlg::CreateMemDCandBitmap() { ReleaseAllObjs( ) ; // Retrieve the width and height of window display elements. long iWidth = m_EnhMetaHeader.szlDevice.cx ; long iHeight = m_EnhMetaHeader.szlDevice.cy ; if( iWidth == 0 || iHeight == 0 ) return FALSE ; HDC hDC = ::GetWindowDC(m_hWnd) ; if( hDC == NULL ) return FALSE ; m_hDCMem = CreateCompatibleDC (hDC); if( m_hDCMem == NULL ) { ::ReleaseDC( m_hWnd , hDC ) ; return FALSE ; } // Create a bitmap compatible with the device associated with the // device context. m_hBitmap = CreateCompatibleBitmap (hDC, iWidth, iHeight); if( m_hBitmap == NULL ) { if( m_hDCMem ) { DeleteDC( m_hDCMem ) ; m_hDCMem = NULL ; } ::ReleaseDC( m_hWnd , hDC ) ; return FALSE ; } HBITMAP oldbitmap; oldbitmap = (HBITMAP) SelectObject( m_hDCMem, m_hBitmap ); RECT rc ; rc.left = 0 ; rc.top = 0 ; rc.right = iWidth ; rc.bottom = iHeight ; FillRect(m_hDCMem, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)) ; ::ReleaseDC( m_hWnd , hDC ) ; return TRUE ; }